package com.cskaoyan.javase.oop1._13block._2building;

import jdk.management.resource.internal.inst.SocketOutputStreamRMHooks;

/**
 * 使用场景
 * 根据构造代码块的特点，分析一下它的实际使用场景
 * 构造代码块最大的特点就是其中的代码会最终加入构造，所以依据这一点：
 * 我们可以“提取公因式”一样的，把所有构造器都需要执行的代码，放入构造代码块中
 *
 * 其次，构造代码块毕竟是给成员变量赋值用的，所以：
 * 如果需要很复杂的代码完成成员变量的赋值（如果只是给一个值，用显式赋值和构造器足矣）
 * 比如需要一个算法，需要一定计算等等。在这些场景下，使用构造代码块是一个不错的选择
 *
 * @since 10:59
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo4 {
    public static void main(String[] args) {
        // 统计在外部创建Phone对象的次数
        Phone p = new Phone();
        Phone p2 = new Phone("三星", "盖乐世S22");
        Phone p3 = new Phone(10000, "苹果", "IPhone");

        System.out.println(Phone.count);

    }
}
class Phone{
    // 创建对象的计数器,应该是一个静态成员变量
    static int count = 0;

    double price;
    String brand;
    String name;

    {
        // 将每个构造器都需要执行的代码放入构造代码块
        /*
            思考count是一个静态成员变量,显然构造代码块是可以给静态成员变量赋值
            因为类加载在前,创建对象在后

            但是这种赋值,意味着静态成员变量的赋值要依赖于创建对象
            除非有特殊需求
            一般这么做是不好的
            所以我们一种代码块,在类加载时完成静态成员变量的赋值
            这就是静态代码块
         */
        count++;
    }

    public Phone(String brand, String name) {
        this.brand = brand;
        this.name = name;
    }

    public Phone() {
    }

    public Phone(double price, String brand, String name) {
        this.price = price;
        this.brand = brand;
        this.name = name;
    }
}